// Copyright (c) Appeon. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

namespace SnapObjects.Data
{
    internal class SqlOrderBuilder : SqlBuilderComb, ISqlOrderBuilder, ISqlOrderThenBuilder
    {
        private readonly SqlBuildClause _clause;

        public SqlOrderBuilder(ISqlBuilder builder, SqlBuildClause clause) : base(builder)
        {
            _clause = clause;
        }

        /// <summary>
        ///     Creates an ORDER BY clause and specifies one or more sort criteria in ascending order.
        /// </summary>
        /// <param name="orderExpressions">
        ///     (Optional) An array of expressions which specify a column or an expression on which to sort the query result set.
        /// </param>
        /// <returns>
        ///     Returns an ISqlOrderThenBuilder object which can be used to add more sort criteria to the current ORDER BY clause.
        /// </returns>
        public ISqlOrderThenBuilder OrderByAscending(params string[] orderExpressions)
        {
            _clause.Add(new OrderElement(orderExpressions, true));

            return this;
        }

        /// <summary>
        ///     Creates an ORDER BY clause and specifies one or more sort criteria in descending order.
        /// </summary>
        /// <param name="orderExpressions">
        ///     (Optional) An array of expressions which specify a column or an expression on which to sort the query result set.
        /// </param>
        /// <returns>
        ///     Returns an ISqlOrderThenBuilder object which can be used to add more sort criteria to the current ORDER BY clause.
        /// </returns>
        public ISqlOrderThenBuilder OrderByDescending(params string[] orderExpressions)
        {
            _clause.Add(new OrderElement(orderExpressions, false));

            return this;
        }

        /// <summary>
        ///     Creates an ORDER BY clause and specifies one or more sort criteria using a raw SQL.
        /// </summary>
        /// <param name="orderClause">A string of raw SQL which specifies one or more sort criteria.</param>
        /// <returns>
        ///     Returns an ISqlOrderThenBuilder object which can be used to add more sort criteria to the current ORDER BY clause.
        /// </returns>
        public ISqlOrderThenBuilder OrderByRaw(string orderClause)
        {
            return this.OrderByRaw(orderClause, "");
        }

        /// <summary>
        ///     Creates an ORDER BY clause; and specifies one or more sort criteria using a raw SQL and specifies an alias for the raw SQL.
        /// </summary>
        /// <param name="orderClause">A string of raw SQL which specifies one or more sort criteria.</param>
        /// <param name="alias">The alias for the raw SQL.</param>
        /// <returns>
        ///     Returns an ISqlOrderThenBuilder object which can be used to add more sort criteria to the current ORDER BY clause.
        /// </returns>
        public ISqlOrderThenBuilder OrderByRaw(string orderClause, string alias)
        {
            _clause.Add(new RawElement(orderClause, alias));

            return this;
        }

        /// <summary>
        ///     Adds one or more sort criteria (in ascending order) to the ORDER BY clause.
        /// </summary>
        /// <param name="orderExpressions">
        ///     (Optional) An array of expressions which specify a column or an expression on which to sort the query result set.
        /// </param>
        /// <returns>
        ///     Returns an ISqlOrderThenBuilder object which can be used to add more sort criteria to the current ORDER BYclause.
        /// </returns>
        public ISqlOrderThenBuilder ThenByAscending(params string[] orderExpressions)
        {
            _clause.Add(new OrderElement(orderExpressions, true));

            return this;
        }

        /// <summary>
        ///     Adds one or more sort criteria (in descending order) to the ORDER BY clause.
        /// </summary>
        /// <param name="orderExpressions">
        ///     (Optional) An array of expressions which specify a column or an expression on which to sort the query result set.
        /// </param>
        /// <returns>
        ///     Returns an ISqlOrderThenBuilder object which can be used to add more sort criteria to the current ORDER BYclause.
        /// </returns>
        public ISqlOrderThenBuilder ThenByDescending(params string[] orderExpressions)
        {
            _clause.Add(new OrderElement(orderExpressions, false));

            return this;
        }

        /// <summary>
        ///     Adds one or more sort criteria specified by raw SQL to the ORDER BY clause.
        /// </summary>
        /// <param name="orderClause">
        ///     A string of raw SQL which specifies one or more sort criteria.
        /// </param>
        /// <returns>
        ///     Returns an ISqlOrderThenBuilder object which can be used to add more sort criteria to the current ORDER BY clause.
        /// </returns>
        public ISqlOrderThenBuilder ThenByRaw(string orderClause)
        {
            return this.ThenByRaw(orderClause, "");
        }

        /// <summary>
        ///     Adds one or more sort criteria specified by raw SQL to the ORDER BY clause, and specifies an alias for the raw SQL.
        /// </summary>
        /// <param name="orderClause">
        ///     A string of raw SQL which specifies one or more sort criteria.
        /// </param>
        /// <param name="alias">
        ///     The alias for the raw SQL.
        /// </param>
        /// <returns>
        ///     Returns an ISqlOrderThenBuilder object which can be used to add more sort criteria to the current ORDER BY clause.
        /// </returns>
        public ISqlOrderThenBuilder ThenByRaw(string orderClause, string alias)
        {
            _clause.Add(new RawElement(orderClause, alias));

            return this;
        }
    }
}
